<?php

/**
 * Created by PhpStorm.
 * Author: ls
 * Time: 2023/10/25 9:18
 * Desc: 拼团
 */
class Service_Api_Together extends Contract_Api_Together
{

    public function query($params): array
    {
        /**
         * @var $page int 页码
         * @var $pagesize int 每页条数
         * @var $status int 拼团策略状态
         * @var $show_total int 是否显示总数
         */
        extract($params);
        $offset = St_Page::offset($page, $pagesize);

        $field = 'id,title,start_date,end_date,sellprice,stock,type_id,product_id,attrid,iconlist';
        $model = DB::select(DB::expr($field))
            ->from('together')
            ->where('is_show', '=', 1);
        if(!empty($params['keyword'])){
            $model->and_where(DB::expr(" AND title like '%".$params['keyword']."%'"));
        }
        if (isset($status)) {
            $now_date = date("Y-m-d H:i:s", time());
            if ($status == Model_Together::TOGETHER_STATUS_WAIT) {
                $model->and_where('start_date', '>', $now_date);
            } elseif ($status == Model_Together::TOGETHER_STATUS_PENDING) {
                $model->and_where('start_date', '<', $now_date);
                $model->and_where('end_date', '>', $now_date);
            }
        }

        $data = array();
        if (isset($show_total) && $show_total) {
            $data['total'] = $model->execute()->count();
        }
        $list = $model->offset($offset)
            ->limit($pagesize)
            ->order_by('id', 'desc')
            ->execute()
            ->as_array();
        // 获取额外参数
        foreach ($list as &$v) {
            $price           = Model_Together_Price::get_mini_price($v);
            $v['price']      = $price ? number_format($price, 2, '.', '') : 0;
            $litpic          = Model_Together_Product::get_litpic($v['type_id'], $v['product_id']);
            $litpic          = $litpic ?: Common::nopic();
            $v['litpic']     = $this->img_url($litpic, 375, 461);
            $v['order_num']  = Model_Together::get_join_total_people_number(array('together_id' => $v['id']));
            $remaining_stock = bcsub($v['stock'], $v['order_num'], 0);
            $v['stock']      = max($remaining_stock, 0);
            $v['id']         = intval($v['id']);
            // 转换为时间戳
            $v['start_date_timestamp'] = strtotime($v['start_date']);
            $v['end_date_timestamp']   = strtotime($v['end_date']);
            // 状态
            $v['status'] = Model_Together::get_status($v);
            // 剩余时间
            $remaining_seconds = 0;
            if ($v['status'] == Model_Together::TOGETHER_STATUS_WAIT) {
                $remaining_seconds = bcsub(strtotime($v['start_date']), time(), 0);
            } elseif ($v['status'] == Model_Together::TOGETHER_STATUS_PENDING) {
                $remaining_seconds = bcsub(strtotime($v['end_date']), time(), 0);
            }
            $v['remaining_seconds'] = max($remaining_seconds, 0) * 1000;
            $v['icon_list']         = Product::get_ico_list($v['iconlist']);
            $v['attrlist']          = Model_Together_Attr::get_attr_list($v['attrid']);
        }
        $data['list'] = $list;
        return $data;
    }

    public function detail($id, bool $need_format = true, array $params = []): array
    {
        $together = DB::select(
            'id', 'title', 'start_date', 'end_date', 'sellprice',
            'stock', 'type_id', 'product_id', 'gather_together_is_open',
            'description', 'together_type', 'allow_discount_type', 'suit_id','allow_member_type'
        )
            ->from('together')
            ->where('id', '=', $id)
            ->where('is_show', '=', 1)
            ->execute()
            ->current();

        if (!$together) {
            throw new Exception('拼团不存在或已下架');
        }
        if($together['allow_member_type'] == 0 || !$params['mid']){
            $together['is_book'] = true;
        }else{
            $allow_member_type = explode(',',$together['allow_member_type']);
            $m_rank = DB::select()->from('member')->where('mid','=',$params['mid'])->execute()->get('grade_id');
            $together['is_book'] = in_array($m_rank,$allow_member_type);
        }
        // 拼团状态
        $together['status']      = Model_Together::get_status($together);
        $together['status_name'] = Model_Together::get_status_name($together);
        $together['id']          = intval($together['id']);
        $together['stock']       = intval($together['stock']);

        if ($need_format) {
            // 获取拼团详情
            $price                       = Model_Together_Price::get_mini_price($together);
            $litpic                      = Model_Together_Product::get_litpic($together['type_id'], $together['product_id']);
            $litpic                      = $litpic ?: Common::nopic();
            $together['litpic']          = $this->img_url($litpic, 375, 461);
            $together['price']           = $price ? number_format($price, 2, '.', '') : 0;
            $together['pic_list']        = Model_Api_V2_Together::get_pic_list($together['type_id'], $together['product_id']);
            $together['order_num']       = Model_Together::get_join_total_people_number(array('together_id' => $together['id']));
            $remaining_stock             = bcsub($together['stock'], $together['order_num'], 0);
            $together['remaining_stock'] = max($remaining_stock, 0);
            $together['series']          = St_Product::product_series($together['type_id'], $together['product_id']);
            $together['description']     = $together['description'] ? Model_Api_V2_Xcx::filter_content($together['description']) : '';
            // 剩余时间
            $together['status'] = Model_Together::get_status($together);
            $remaining_seconds  = 0;
            if ($together['status'] == Model_Together::TOGETHER_STATUS_WAIT) {
                $remaining_seconds = bcsub(strtotime($together['start_date']), time(), 0);
            } elseif ($together['status'] == Model_Together::TOGETHER_STATUS_PENDING) {
                $remaining_seconds = bcsub(strtotime($together['end_date']), time(), 0);
            }
            $together['remaining_seconds'] = max($remaining_seconds, 0) * 1000;

            // 获取可凑团列表
            $together['join_list'] = Model_Api_V2_Together::get_pending_join_list($together, 0, 3);

            // 获取单独购买产品的价格
            $together['product_price'] = Model_Together_Product::get_product_price($together['type_id'], $together['product_id'], $together['suit_id']);
            // 转换为时间戳
            $together['start_date_timestamp'] = strtotime($together['start_date']);
            $together['end_date_timestamp']   = strtotime($together['end_date']);
        }

        return $together;
    }

    public function pending_join_list($id, int $start = 0, int $limit = 100): array
    {
        $together = $this->detail($id, false);

        return Model_Api_V2_Together::get_pending_join_list($together, 0, 100);
    }

    public function order_limit($id): array
    {
        $together = $this->detail($id, false);

        // 优惠券使用限制
        return Model_Api_V2_Together::make_allow_discount_type_data($together);
    }

    public function get_member_join($mid, $params): array
    {
        /**
         * @var $type int 拼团状态 1 拼团中 2 已成团
         * @var $page
         * @var $pagesize
         */
        extract($params);

        $offset = St_Page::offset($page, $pagesize);

        $builder = DB::select(DB::expr('sline_together_join.*,sline_together_order.order_id'))
            ->from('together_order')
            ->join('together_join', 'inner')
            ->on('together_join.id', '=', DB::expr('sline_together_order.join_id'))
            ->where('together_order.member_id', '=', $mid);
        if ($type) {
            if ($type == 1) {
                $builder->and_where('together_join.status', '=', Model_Together_Join::JOIN_STATUS_PENDING);
            } else if ($type == 2) {
                $builder->and_where('together_join.status', '=', Model_Together_Join::JOIN_STATUS_SUCCESS);
            }
        } else {
            $builder->and_where('together_join.status', 'in',
                array(
                    Model_Together_Join::JOIN_STATUS_SUCCESS,
                    Model_Together_Join::JOIN_STATUS_PENDING,
                    Model_Together_Join::JOIN_STATUS_FAIL,
                )
            );
        }

        $total = $builder->execute()->count();

        if (isset($offset) && $offset) {
            $builder->offset($offset);
        }
        if (isset($pagesize) && $pagesize) {
            $builder->limit($pagesize);
        }

        $data = $builder->order_by('together_order.id', 'DESC')->execute()->as_array();
        $list = array();
        foreach ($data as $item) {
            $order = DB::select('litpic', 'productautoid', 'typeid', 'paytime', 'usedate', 'departdate')
                ->from('member_order')
                ->where('id', '=', $item['order_id'])
                ->execute()
                ->current();

            // 封面
            $litpic = $this->img_url($order['litpic']);

            // 已参团数
            $join_num = Model_Together_Order::count_join_num($item['id']);

            // 剩余可拼团数
            $left_num = bcsub($item['together_num'], $join_num, 0);
            $left_num = max($left_num, 0);

            // 如果拼团已完成,满团人数等于参团人数
            $together_num = $item['status'] == Model_Together_Join::JOIN_STATUS_SUCCESS ? $join_num : $item['together_num'];

            // 参团人员
            $virtual_num  = $item['status'] == Model_Together_Join::JOIN_STATUS_SUCCESS ? $left_num : 0; // 需要虚拟成团的人员
            $join_members = Model_Api_V2_Together::get_join_members($item['id'], $item['member_id'], $virtual_num);

            // 是否可以参团
            $can_join = true;
            if ($item['status'] == Model_Together_Join::JOIN_STATUS_SUCCESS) {
                $can_join = false;
                $together = Model_Together::get_info($item['together_id']);
            } else {
                try {
                    // 是否可以参团
                    $together = Model_Api_V2_Together::check_together_booking($item['together_id']);
                } catch (Exception $e) {
                    $can_join = false;
                }
            }

            // 价格
            if (isset($together) && $together) {
                $price = Model_Together_Price::get_mini_price($together);
                $price = $price ? number_format($price, 2, '.', '') : 0;
            }

            // 剩余时间
            $remaining_seconds = 0;
            if ($item['status'] == Model_Together_Join::JOIN_STATUS_PENDING) {
                $remaining_seconds = bcsub($item['expire_time'], time(), 0);
                $remaining_seconds = max($remaining_seconds, 0) * 1000;
            }

            $list[] = array(
                'join_id' => $item['id'],
                'together_title' => $item['title'],
                'join_status' => $item['status'],
                'together_num' => $together_num,
                'product_name' => $item['product_title'],
                'end_time' => $item['expire_time'],
                'join_num' => $join_num,
                'pay_time' => $order['paytime'] ? date('Y-m-d H:i', $order['paytime']) : '',
                'use_date' => $order['usedate'] ?: '',
                'depart_date' => $order['departdate'] ?: '',
                'type_id' => $order['typeid'],
                'order_id' => $item['order_id'],
                'litpic' => $litpic,
                'join_members' => $join_members,
                'price' => $price ?? '',
                'can_join' => $can_join,
                'remaining_seconds' => $remaining_seconds,
            );
        }

        return array('total' => $total, 'list' => $list);
    }

    public function get_member_join_detail($mid, $join_id): array
    {
        $join = DB::select(DB::expr('sline_together_join.*,sline_together_order.order_id'))
            ->from('together_order')
            ->join('together_join', 'inner')
            ->on('together_join.id', '=', DB::expr('sline_together_order.join_id'))
            ->where('together_order.member_id', '=', $mid)
            ->and_where('together_join.id', '=', $join_id)
            ->and_where('together_join.status', 'in',
                array(
                    Model_Together_Join::JOIN_STATUS_SUCCESS,
                    Model_Together_Join::JOIN_STATUS_PENDING
                )
            )->execute()
            ->current();
        if (!$join) {
            throw new Exception('拼团不存在');
        }

        $order = DB::select('litpic', 'productautoid', 'typeid', 'paytime', 'usedate', 'departdate')
            ->from('member_order')
            ->where('id', '=', $join['order_id'])
            ->execute()
            ->current();

        // 封面
        $litpic = $this->img_url($order['litpic']);

        // 已参团数
        $join_num = Model_Together_Order::count_join_num($join_id);

        // 剩余可拼团数
        $left_num = bcsub($join['together_num'], $join_num, 0);
        $left_num = max($left_num, 0);

        // 如果拼团已完成,满团人数等于参团人数
        $together_num = $join['status'] == Model_Together_Join::JOIN_STATUS_SUCCESS ? $join_num : $join['together_num'];

        // 获取拼团规则
        $together = Model_Together::get_info($join['together_id']);

        // 参团人员
        $virtual_num  = $join['status'] == Model_Together_Join::JOIN_STATUS_SUCCESS ? $left_num : 0; // 需要虚拟成团的人员
        $join_members = Model_Api_V2_Together::get_join_members($join_id, $join['member_id'], $virtual_num);

        $price    = ''; //拼团价
        $can_join = true; // 是否可以参团
        if ($join['status'] == Model_Together_Join::JOIN_STATUS_SUCCESS) {
            $can_join = false;
            // 拼团
            $together = Model_Together::get_info($join['together_id']);
        } else {
            try {
                // 是否可以参团
                $together = Model_Api_V2_Together::check_together_booking($join['together_id']);
            } catch (Exception $e) {
                $can_join = false;
            }
        }

        // 价格
        if (isset($together) && $together) {
            $price = Model_Together_Price::get_mini_price($together);
            $price = $price ? number_format($price, 2, '.', '') : 0;
        }

        // 剩余时间
        $remaining_seconds = 0;
        if ($join['status'] == Model_Together_Join::JOIN_STATUS_PENDING) {
            $remaining_seconds = bcsub($join['expire_time'], time(), 0);
            $remaining_seconds = max($remaining_seconds, 0) * 1000;
        }

        return array(
            'join_id' => $join['id'],
            'together_id' => $join['together_id'],
            'together_title' => $join['title'],
            'join_status' => $join['status'],
            'together_num' => $together_num,
            'product_name' => $join['product_title'],
            'end_time' => $join['expire_time'],
            'join_num' => $join_num,
            'pay_time' => $order['paytime'] ? date('Y-m-d H:i', $order['paytime']) : '',
            'use_date' => $order['usedate'] ?: '',
            'depart_date' => $order['departdate'] ?: '',
            'type_id' => $order['typeid'],
            'order_id' => $join['order_id'],
            'litpic' => $litpic,
            'description' => $together['description'] ?? '',
            'join_members' => $join_members,
            'price' => $price ?? '',
            'can_join' => $can_join,
            'remaining_seconds' => $remaining_seconds,
        );
    }

    public function get_share_info($mid, $params): array
    {
        $join_id   = Arr::get($params, 'join_id');
        $come_from = Arr::get($params, 'come_from');

        $join = $this->get_member_join_detail($mid, $join_id);

        $service = Model_Together_Share_Factory::make($come_from);
        $title   = Model_Sysconfig::get_sys_conf('value', 'cfg_together_start_content');
        $url     = '';
//        $code = '';
        if ($service) {
            $url = $service->get_url($join);
            //  $code = $share->get_code($join);
        }
        return array(
            'url' => $url,
            'title' => $title ?: $join['together_title']
            //  'code' => $code
        );
    }
}